﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BlamanticUI.Components;

public class ToastController : IDisposable
{
    private Timer _timer;


    internal ToastController(ToastSetting setting)
    {
        Setting = setting;
        _timer = new Timer(TimerElapsed, null, Timeout.Infinite, Timeout.Infinite);
        StateStyle=new ToastStateStyle(setting);
    }
    public ToastSetting Setting { get; }
    public ToastStateStyle StateStyle { get; }

    public event Action<ToastController> OnClosing;
    public event Action OnUpdating;

    internal void Init() => TransitionTo(ToastState.Showing);

    void TransitionTo(ToastState state)
    {
        this.DebugLine(nameof(TransitionTo), $"当前状态：{state}");
        StopTimer();

        StateStyle.ToastState=state;

        if (state.IsShowing())
        {
            Transit(Setting.ShowDuration, ToastState.Visible,TransitionTo);
        }
        else if (state.IsVisible())
        {
            Transit(Setting.VisibleDuration, ToastState.Hiding,TransitionTo);
        }
        else if (state.IsHiding())
        {
            Transit(Setting.HideDuration, ToastState.Hiding, s => OnClosing?.Invoke(this));
        }
        OnUpdating?.Invoke();

        void Transit(int? duration, ToastState? nextState,Action<ToastState> nextAction)
        {
            this.DebugLine(nameof(Transit), $"持续时间:{duration}ms，下一个状态：{nextState}");

            if (!duration.HasValue)
            {
                if (nextState.HasValue)
                {
                    this.DebugLine(nameof(Transit), "开始下一步 action");
                    nextAction(nextState.Value);
                }
            }
            else
            {
                StartTimer(duration);
            }
        }

    }


    private void TimerElapsed(object state)
    {
        this.DebugLine(nameof(TimerElapsed), $"{Setting.State}-{StateStyle.AnimationId}， 当前状态：{StateStyle.ToastState}");
        switch (StateStyle.ToastState)
        {
            case ToastState.Showing:
                TransitionTo(ToastState.Visible);
                break;
            case ToastState.Visible:
                TransitionTo(ToastState.Hiding);
                break;
            case ToastState.Hiding:
                OnClosing?.Invoke(this);
                break;
        }
    }

    void StartTimer(int? duration)
    {
        StateStyle.TransitionStartTime = DateTime.Now;
        if (duration.HasValue)
        {
            this.DebugLine(nameof(StartTimer),$"延迟{duration}ms启动计时器");
            _timer?.Change(duration.Value, Timeout.Infinite);
        }
    }

    void StopTimer()
    {
        this.DebugLine(nameof(StopTimer), $"停止计时器");
        if (_timer is not null)
        {
            _timer?.Change(Timeout.Infinite, Timeout.Infinite);
        }
    }

    #region Dispose Pattern
    protected virtual void Dispose(bool disposing)
    {
        if (!disposing)
        {
            return;
        }

        StopTimer();
        _timer.Dispose();
        _timer = null;
        this.DebugLine(nameof(Dispose), $"释放");
    }

    // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
    // ~ToastController()
    // {
    //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
    //     Dispose(disposing: false);
    // }

    public void Dispose()
    {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }
    #endregion
}
